package com.tangula.android.base.application

import android.app.Application
import android.util.Log
import com.tangula.android.http.HttpBase
import com.tangula.android.utils.ApplicationUtils
import com.tangula.utils.function.BiConsumer
import com.tangula.utils.function.Consumer
import com.tangula.utils.function.Function
import com.tangula.utils.function.Supplier

@Suppress("UNCHECKED_CAST")
abstract class BaseApplication<U>(val serverUrl:String, val curUserIdFetch:Function<U, String>) : Application(){

    private var user: U? = null

    init {
        updateCurrentApplication(this)
        ApplicationUtils.APP=this
    }

    override fun onCreate() {
        HttpBase.URL_PREFIX = serverUrl
        HttpBase.USER_ID_SUPPLIER = Supplier { curUserIdFetch(fetchUser())}
        HttpBase.FUNC_LOG_VERB = Consumer { it ->
            Log.v(LOG_TAG_HTTP, it)
        }
        HttpBase.FUNC_LOG_WARN = BiConsumer { msg, e ->
            Log.w(LOG_TAG_HTTP, msg, e)
        }
        HttpBase.FUNC_LOG_ERROR = BiConsumer { msg, e ->
            Log.e(LOG_TAG_HTTP, msg, e)
        }

        super.onCreate()
    }

    fun fetchUser():U? {
        return user
    }

    fun updateUser(user:U){
        this.user = user
    }

    companion object {

        @JvmStatic
        val LOG_TAG_HTTP = "http"

        @JvmStatic
        private var CURRENT_APP: BaseApplication<*>? = null

        @JvmStatic
        fun getCurrentApplication(): BaseApplication<*> {
            return CURRENT_APP!!
        }

        @JvmStatic
        fun updateCurrentApplication(app:BaseApplication<*>){
            if(CURRENT_APP!=null) {
                CURRENT_APP = app
            }
        }

        @JvmStatic
        fun getCurrentUser(): Any? {
            return getCurrentApplication().fetchUser()
        }


        @JvmStatic
        fun <U> updateCurrentUser(user:U) {
            (CURRENT_APP as BaseApplication<U>).updateUser(user)
        }

        @JvmStatic
        fun <U> getCurUserId():String{
            return (getCurrentApplication() as BaseApplication<U>) .curUserIdFetch.invoke(getCurrentUser() as U)?:""
        }

    }
}